﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;

using MW.Domain.DC;
using MW.Service;

using System.Text.RegularExpressions; 

namespace MW.App
{
    public partial class FrmDC : Form
    {
        public FrmDC()
        {
            InitializeComponent();

            Init();
        }

        #region Method

        private void Init()
        {
            LstPanel.Add(pnlFile);
            LstPanel.Add(pnlProcess);
        }

        private void ShowPanel(int index)
        {
            foreach (Panel pItem in lstPanel)
            {
                pItem.Visible = false;
            }

            lstPanel[index].Visible = true;
        }

        private IList<Meta> ParseMARC(XmlDocument document)
        {
            IList<Meta> lstReturn = new List<Meta>();
            MetaService mService = MetaService.GetInstance();

            XmlNamespaceManager xnmDocument = new XmlNamespaceManager(document.NameTable);
            xnmDocument.AddNamespace("collection", "http://www.loc.gov/MARC21/slim");
            xnmDocument.AddNamespace("record", "http://www.loc.gov/MARC21/slim");

            XmlNodeList xnList = document.SelectNodes("collection:collection/record:record", xnmDocument);

            double decStep = 100.0 / xnList.Count;
            double decProcess = 0;

            for (int i = 0; i < xnList.Count; i++)
            {
                Meta mItem = new Meta();
                MetaDC mdcItem = new MetaDC();
                RecLink rlItem = new RecLink();
                mItem.MetaDCs.Add(mdcItem);
                mItem.RecLinks.Add(rlItem);
                mItem.RID = "00001";
                mItem.Datestamp = DateTime.Now;

                mdcItem.MARC_XML = xnList[i].OuterXml;

                foreach (XmlNode xnField in xnList[i].ChildNodes)
                {
                    if (xnField.Name.ToString().IndexOf("field") >= 0)
                    {
                        switch (xnField.Attributes["tag"].Value)
                        {
                            case "001":
                                mItem.RecID = xnField.FirstChild.Value;
                                break;
                            case "010":
                                foreach (XmlNode xnItem in xnField.ChildNodes)
                                {
                                    if (xnItem.Attributes["code"].Value == "a")
                                    {
                                        mItem.RecID += "|" + xnItem.FirstChild.Value;
                                    }
                                }
                                break;
                            case "101":
                                mdcItem.Language = ConnectSubNode(xnField, mdcItem.Language);
                                break;
                            case "205":
                                for (int j = 0; j < xnField.ChildNodes.Count; j++)
                                {
                                    if (xnField.ChildNodes[j].Attributes["code"].Value == "f"
                                        || xnField.ChildNodes[j].Attributes["code"].Value == "g")
                                    {
                                        mdcItem.Contributor += xnField.ChildNodes[j].FirstChild.Value + "|";
                                    }
                                }
                                mdcItem.Contributor = RemoveLastCharacter(mdcItem.Contributor);
                                break;
                            case "200":
                                mdcItem.Title += ConnectSubNode(xnField, mdcItem.Title);
                                break;
                            case "210":
                                for (int j = 0; j < xnField.ChildNodes.Count; j++)
                                {
                                    if (xnField.ChildNodes[j].Attributes["code"].Value == "c")
                                    {
                                        mdcItem.Publisher = xnField.ChildNodes[j].FirstChild.Value;
                                    }
                                    else if (xnField.ChildNodes[j].Attributes["code"].Value == "d")
                                    {
                                        mdcItem.Date = xnField.ChildNodes[j].FirstChild.Value;
                                    }
                                }
                                break;
                            case "215":
                                mdcItem.Description += ConnectSubNode(xnField, mdcItem.Description);
                                break;
                            case "225":
                                mdcItem.Relation += ConnectSubNode(xnField, mdcItem.Relation);
                                break;
                            case "320":
                                mdcItem.Description += ConnectSubNode(xnField, mdcItem.Description);
                                break;
                            case "330":
                                mdcItem.Description += ConnectSubNode(xnField, mdcItem.Description);
                                break;
                            case "600":
                                mdcItem.Subject += ConnectSubNode(xnField, mdcItem.Subject);
                                break;
                            case "601":
                                mdcItem.Subject += ConnectSubNode(xnField, mdcItem.Subject);
                                break;
                            case "606":
                                mdcItem.Subject += ConnectSubNode(xnField, mdcItem.Subject);
                                break;
                            case "690":
                                mdcItem.Subject += ConnectSubNode(xnField, mdcItem.Subject);
                                break;
                            case "701":
                                mdcItem.Creator += ConnectSubNode(xnField, mdcItem.Creator);
                                break;
                            case "702":
                                mdcItem.Contributor += ConnectSubNode(xnField, mdcItem.Contributor);
                                break;
                            case "712":
                                mdcItem.Contributor += ConnectSubNode(xnField, mdcItem.Contributor);
                                break;
                            case "722":
                                mdcItem.Contributor += ConnectSubNode(xnField, mdcItem.Contributor);
                                break;
                            case "730":
                                mdcItem.Contributor += ConnectSubNode(xnField, mdcItem.Contributor);
                                break;
                        }
                    }
                }

                mItem.UniqueID = mItem.RID + mItem.RecID;

                mService.InsertMeta(mItem);
                lstReturn.Add(mItem);

                decProcess += decStep;
                this.pbrProcess.Value = Convert.ToInt16(decProcess);
                this.lblDescription.Text = mItem.RecID;
                Application.DoEvents();
            }

            return lstReturn;
        }

        private bool ContainChineseChar(string strInput)
        {
            bool bolReturn = false;
            Regex r = new Regex(@"[\u4e00-\u9fa5]+");   

            foreach (char cItem in strInput)
            {
                if (r.Match(cItem.ToString()).Success)
                {
                    bolReturn = true;
                    break;
                }
            }
            return bolReturn;
        }

        private string ConnectSubNode(XmlNode xmlNode, string strOriginal)
        {
            string strReturn = "";

            if (!string.IsNullOrEmpty(strOriginal))
            {
                strReturn = strOriginal + "|";
            }

            XmlNode xnSub = null;
            for (int i = 0; i < xmlNode.ChildNodes.Count; i++)
            {
                xnSub = xmlNode.ChildNodes[i];
                if (xnSub.FirstChild.Value.Length > 0
                    && (Convert.ToChar(xnSub.Attributes["code"].Value) >= 'a' && Convert.ToChar(xnSub.Attributes["code"].Value) <= 'z'))
                {
                    strReturn += xnSub.FirstChild.Value + "|";
                }
            }

            return RemoveLastCharacter(strReturn);
        }

        private string RemoveLastCharacter(string strInput)
        {
            if (strInput.Length > 0)
            {
                strInput = strInput.Substring(0, strInput.Length - 1);
            }
            return strInput;
        }

        private XmlDocument OpenMARCXML(string fileName)
        {
            if (!System.IO.File.Exists(fileName))
            {
                throw new Exception("File Cannot be found.");
            }

            XmlDocument docReturn = new XmlDocument();
            docReturn.Load(fileName);
            return docReturn;
        }

        #endregion

        #region Event

        private void btnFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofdTemp = new OpenFileDialog();
            ofdTemp.Filter = "*.xml|*.xml";
            if (ofdTemp.ShowDialog() == DialogResult.OK)
            {
                this.txtFileName.Text = ofdTemp.FileName;
            }
        }

        private void btn2_Click(object sender, EventArgs e)
        {
            if (this.pnlProcess.Visible)
            {
                this.Close();
            }

            if (iPanelIndex < lstPanel.Count - 1)
            {
                iPanelIndex++;
                ShowPanel(iPanelIndex);
            }
        }

        private void btn1_Click(object sender, EventArgs e)
        {
            if (iPanelIndex > 0)
            {
                iPanelIndex--;
                ShowPanel(iPanelIndex);
            }
        }

        private void pnlProcess_VisibleChanged(object sender, EventArgs e)
        {
            try
            {
                if (this.pnlProcess.Visible)
                {
                    this.btn1.Enabled = true;
                    this.btn2.Text = "完成";
                    this.btn2.Enabled = false;

                    Application.DoEvents();
                    IList<Meta> lstMeta = ParseMARC(OpenMARCXML(this.txtFileName.Text.Trim()));

                    this.lblDescription.Text = "";
                    this.lblProcess.Text = "导入已完成，成功导入" + lstMeta.Count + "条记录。";

                    this.btn2.Enabled = true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void pnlFile_VisibleChanged(object sender, EventArgs e)
        {
            this.btn1.Enabled = false;
            this.btn2.Enabled = true;
            this.btn2.Text = "下一步";
        }

        #endregion

        #region Property

        private int iPanelIndex = 0;

        private IList<Panel> lstPanel = new List<Panel>();

        public IList<Panel> LstPanel
        {
            get { return lstPanel; }
            set { lstPanel = value; }
        }

        #endregion
    }
}
